package com.joysuch.wwyt.bp.service.impl;

import com.joysuch.wwyt.bp.service.BpSmsService;
import com.joysuch.wwyt.config.RedisClient;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.entity.BaseLoginAccount;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.repository.BaseLoginAccountDao;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.util.SmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author ZhangDong
 * @Date 2021/2/20 16:00
 */
@Service
@Slf4j
public class BpSmsServiceImpl implements BpSmsService {

    // 阿里云获取的访问API密钥
    @Value("${sms.access.key.id}")
    private String accessKeyId;
    @Value("${sms.access.key.secret}")
    private String accessKeySecret;
    //短信签名,即最前面在【】这个中的文字,可以打开手机随便看一条商业短信,例：【淘宝】亲爱的用户.....
    @Value("${sms.sign.name}")
    private String signName;
    // 短信模板,即在阿里云短信服务中自己创建的短信模板ID
    @Value("${sms.template.code}")
    private String templateCode;

    private Pattern pattern = Pattern.compile("^1[0-9]{10}$");
    @Autowired
    private BaseLoginAccountDao baseLoginAccountDao;
    @Resource
    private RedisClient redisClient;
    @Autowired
    private BaseConfigService baseConfigService;

    @Override
    public ResultBean send(String phone) {
        Assert.notNull(phone, "phone cannot be null");
        Matcher matcher = pattern.matcher(phone);
        if (!matcher.matches()) {
            return ResultBean.fail(101, "手机号不符合要求");
        }
        Long currentUserId = Context.getCurrentUserId();
        BaseLoginAccount account = baseLoginAccountDao.findByUserDetailId(currentUserId);
        //如果账号被禁用，给提示
        Assert.notNull(account, "此账号不存在");
        if (account.getShowState() != null && account.getShowState() == 0) {
            return ResultBean.fail(101, "此账号已被禁用");
        }
        String key = getRedisKey(account);
        synchronized (key) {
            Integer verifyCode = ThreadLocalRandom.current().nextInt(100000, 999999);
            boolean success = SmsUtil.sendSms(phone, verifyCode.toString(), accessKeyId, accessKeySecret, signName, templateCode);
            if (success) {
                redisClient.setEx(key, verifyCode.toString(), 30, TimeUnit.MINUTES);
                log.info("短消息发送成功，phone:{}", phone);
            } else {
                log.error("短消息发送失败，phone:{}", phone);
                return ResultBean.fail(101, "发送失败，请重新发送");
            }
            return ResultBean.defaultSuccessResult();
        }
    }

    @Override
    public ResultBean verify(String verifyCode) {
        Assert.notNull(verifyCode, "验证码不能为空");
        Long currentUserId = Context.getCurrentUserId();
        BaseLoginAccount account = baseLoginAccountDao.findByUserDetailId(currentUserId);
        //如果账号被禁用，给提示
        Assert.notNull(account, "此账号不存在");
        if (account.getShowState() != null && account.getShowState() == 0) {
            return ResultBean.fail(101, "此账号已被禁用");
        }
        String key = getRedisKey(account);
        String exist = redisClient.get(key);
        if (exist == null || !verifyCode.equals(exist)) {
            return ResultBean.fail(101, "验证不成功，请重新发送验证码");
        }
        BaseConfig config = baseConfigService.findFirstConfig(BaseConfigCodes.SMS_SURVIVE_TIME);
        if (config == null) {
            return ResultBean.success(1);
        }
        return ResultBean.success(config.getValue());
    }

    @Override
    public String getRedisKey(BaseLoginAccount account) {
        return "sms:" + account.getTenentId() + ":" + account.getOrgCode().substring(0, 7)
                + ":" + account.getUserName() + ":" + account.getBaseUser().getId();
    }

}
